﻿using Microsoft.Extensions.Primitives;

namespace Acl.Messages.Impl;

/// <summary>
/// 订阅到的远程消息
/// </summary>
/// <param name="Topic">消息主题</param>
/// <param name="ReplyTo">回复的消息主题</param>
/// <param name="Size">负载数据的大小</param>
/// <param name="Headers">消息头</param>
/// <param name="Data">数据</param>
/// <param name="Publisher">消息发布器</param>
readonly record struct DistributedMessage<TData>(string Topic, string? ReplyTo, int Size, IDictionary<string, StringValues>? Headers, TData? Data, IDistributionMessagePublisher Publisher) : IDistributionMessage<TData>
{
    /// <summary>
    /// 回复消息
    /// </summary>
    /// <param name="data">回复的负载数据</param>
    /// <param name="opts">回复时参数选项</param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    public ValueTask ReplyAsync<TReplyData>(TReplyData data, in DistributionPublishOptions? opts = default, CancellationToken cancellationToken = default)
    {
        CheckReplyPreconditions();
        return Publisher.Publish(ReplyTo!, data, opts, cancellationToken);
    }

    [MemberNotNull(nameof(Publisher))]
    private void CheckReplyPreconditions()
    {
        if (Publisher == default)
        {
            throw new InvalidOperationException("unable to send reply; message did not originate from a subscription");
        }

        if (string.IsNullOrWhiteSpace(ReplyTo))
        {
            throw new InvalidOperationException("unable to send reply; ReplyTo is empty");
        }
    }
}